home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / hypercrd / xcmd / dxcmds34.sit / Dartmouth XCMD's 3.4.3 / card_13535.txt < prev    next >
Text File  |  1990-04-17  |  15KB  |  444 lines

  1. -- card: 13535 from stack: in.3
  2. -- bmap block id: 0
  3. -- flags: 4000
  4. -- background id: 3241
  5. -- name: GetResources
  6. ----- HyperTalk script -----
  7. on Install
  8.   get ChooseTargetStack()
  9.   InstallResource XCMD,GetResources,it
  10. end Install
  11.  
  12.  
  13. -- part 1 (button)
  14. -- low flags: 00
  15. -- high flags: A003
  16. -- rect: left=299 top=300 right=322 bottom=438
  17. -- title width / last selected line: 0
  18. -- icon id / first selected line: 0 / 0
  19. -- text alignment: 1
  20. -- font id: 0
  21. -- text size: 12
  22. -- style flags: 0
  23. -- line height: 16
  24. -- part name: Show Pascal Source
  25. ----- HyperTalk script -----
  26. on mouseUp
  27.   set the visible of card field 1 to not the visible of card field 1
  28.   if the visible of card field 1 is true then
  29.     set the name of me to "Hide Pascal Source"
  30.   else set the name of me to "Show Pascal Source"
  31. end mouseUp
  32.  
  33.  
  34.  
  35. -- part 2 (field)
  36. -- low flags: 81
  37. -- high flags: 2007
  38. -- rect: left=12 top=26 right=298 bottom=491
  39. -- title width / last selected line: 0
  40. -- icon id / first selected line: 0 / 0
  41. -- text alignment: 0
  42. -- font id: 22
  43. -- text size: 10
  44. -- style flags: 0
  45. -- line height: 13
  46. -- part name: Source
  47.  
  48.  
  49. -- part contents for background part 16
  50. ----- text -----
  51. GETRESOURCES XCMD version 1.6
  52. Kevin Calhoun
  53.  
  54. The GetResources XCMD is intended for XCMD and XFCN developers who need a fast way to copy resources into a stack for testing.  For XCMD and XFCN users who want to copy resources from one stack to another, the ResCopy XCMD by Steve Maller is more appropriate than GetResources.
  55.  
  56. GetResources copies resources to the current stack from a file designated by full pathname.  The set of resources to be copied from that file can be defined in three different ways:
  57.  
  58.   1)  all resources of type XCMD or XFCN in the file,
  59.   2)  all the resources found in the file other than resources of type CODE, FREF, or     
  60.         BNDL, which have been determined to be harmful to the operating system when 
  61.         copied indiscriminately, and
  62.   3)  all resources in the file of the types you specify.
  63.  
  64. GetResources does not rename or renumber resources before adding them to the current stack;  instead, it will remove any resource already contained in the current stack that has the same name and type (or the same ID and type) as a resource that it copies to the stack.  If the current stack has no resource fork, GetResources will add a resource fork to the stack before copying resources to it.
  65.  
  66. As with other resource copiers, if you use GetResources to copy a resource into the Home stack, you may have to quit and relaunch HyperCard in order to use it.
  67.  
  68. WHY DID I WRITE THIS WHEN PERFECTLY GOOD RESOURCE COPIERS EXIST ALREADY?...
  69.  
  70. There was no way to copy resources blindly from one file to another.  I wanted a way to say, "Get me whatever's over there and put it here, and don't keep asking me if it's OK."
  71.  
  72. INVOKING GETRESOURCES
  73.  
  74. GetResources "sourceFile","listOfTypes" 
  75.  
  76. GetResources takes two parameters, the second of which is optional.
  77.  
  78. Parameter 1:  the file name (full pathname) of the file to copy from.
  79. Parameter 2:  the types of resources to copy.  If the second parameter is not present, GetResources copies only the XFCN's and XCMD's found in the specified file.  If you pass the string "ALL" for this parameter, GetResources will copy all the resources found in the file (excepting CODE, FREF, and BNDL resources).  If this parameter is anything other than "ALL", it is interpreted as a list of resource types to copy.
  80.  
  81. Examples:
  82.  
  83. GetResources "Dr.HD:HyperCard ╞Æ:HyperCard Stacks:Developer Stack 1.3","ALL"
  84.    --copies all resources from Developer Stack 1.3 to the current stack (excepting the 
  85.    --types noted above)
  86.  
  87. GetResources "My HD:System Folder:System","ICON,PICT"
  88.    --copies all ICON and PICT resources found in the System File into the current stack
  89.  
  90. GetResources "Old Peculier:Hyper ╞Æ:HyperCard Stacks:Home"
  91.    --copies all XCMD and XFCN resources found in the home stack into the current stack
  92.  
  93. In case anybody asks, it's true that I wrote DeleteResFork in order to recover from bad things that happened while I was developing GetResources.
  94.  
  95. Revision history:
  96. 15 March 1989 -- first release.
  97. 11 June 1989 -- Minor change for compatibility with SuperCard.  GetResources checks whether HyperCard is running after copying the resources and goes home and back only under HyperCard.
  98. 22 July 1989 -- No longer leaves a NIL master pointer behind when replacing a resource.
  99.  
  100. -- part contents for card part 2
  101. ----- text -----
  102. UNIT AutoResUnit;
  103.  
  104. { GetResources XCMD ┬⌐ 1988-1989 by the Trustees of Dartmouth College }
  105. { Written by Kevin Calhoun }
  106.  
  107. { This source compatible with MPW Pascal 3.0 }
  108.  
  109. (*
  110. Pascal GetResources.p
  111. Link -m ENTRYPOINT Γêé
  112.      -o "YourFile" Γêé
  113.      -rt XCMD=7449 Γêé
  114.      -sn Main=GetResources Γêé
  115.      GetResources.p.o Γêé
  116.     "{Libraries}"interface.o Γêé
  117.     "{PLibraries}"Paslib.o Γêé
  118.     "{Libraries}"HyperXLib.o
  119. *)
  120.  
  121. {$R-}
  122.  
  123. INTERFACE
  124.   USES
  125.     Types,
  126.     Memory,
  127.     Resources,
  128.     Files,
  129.     Errors,
  130.     SysEqu,
  131.     ToolUtils,
  132.     HyperXCmd;
  133.  
  134.   PROCEDURE EntryPoint (paramPtr : XCmdPtr);
  135.  
  136. IMPLEMENTATION
  137.  
  138.   TYPE ToGrab = (extensions, all, userType);
  139.  
  140.   PROCEDURE GetResources(paramPtr : XCmdPtr); FORWARD;
  141.  
  142.   PROCEDURE EntryPoint (paramPtr : XCmdPtr);
  143.   BEGIN
  144.     GetResources(paramPtr);
  145.   END;
  146.  
  147.   FUNCTION MyOpenResFile(fileName: Str255; VAR refNum: INTEGER;
  148.                           VAR wasOpen: BOOLEAN): OSErr;
  149.     TYPE
  150.       HandlePtr = ^Handle;
  151.     VAR
  152.       oldTopMapHndl: Handle;
  153.   BEGIN
  154.     MyOpenResFile := noErr;
  155.     oldTopMapHndl := HandlePtr(TopMapHndl)^;  { remember current TopMapHndl }
  156.     refNum := OpenResFile(fileName);          { open resource file }
  157.     IF (refNum = -1) THEN { error opening file }
  158.       BEGIN
  159.       MyOpenResFile := ResError;
  160.       EXIT(MyOpenResFile);
  161.       END
  162.     ELSE
  163.       IF (oldTopMapHndl = HandlePtr(TopMapHndl)^) THEN wasOpen := TRUE
  164.         { no change -- it was open }
  165.       ELSE wasOpen := FALSE;
  166.         { res file wasn't open before }
  167.   END;
  168.  
  169.   FUNCTION GetFullPathnameOfThisStack (paramPtr : XCMDPtr; var str: Str255) : OSErr;
  170.     VAR
  171.       theResult : Handle;
  172.       theLength : Longint;
  173.       err: OSErr;
  174.   BEGIN
  175.     err := noErr;
  176.     str := 'word 2 of the long name of this stack';
  177.     theResult := EvalExpr(paramPtr, str);
  178.     err := paramPtr^.result;
  179.     IF (theResult <> NIL) and (err = noErr) THEN
  180.       BEGIN
  181.       theLength := StringLength(paramPtr, theResult^);
  182.       ZeroToPas(paramPtr, theResult^, str);
  183.       DisposHandle(theResult);
  184.       DELETE(str,theLength,1);
  185.       DELETE(str,1,1);
  186.       END
  187.     ELSE str := '';
  188.     GetFullPathnameOfThisStack := err;
  189.   END;
  190.   
  191.   FUNCTION OpenAndMaybeCreateResFile (theFile : Str255; VAR fRefNum: INTEGER) : OSErr;
  192.     VAR
  193.       err : OSErr;
  194.   BEGIN
  195.     err := noErr;
  196.     fRefNum := OpenResFile(theFile);
  197.     err := ResError;
  198.     IF (fRefNum = -1) AND (err = eofErr) THEN
  199.       BEGIN
  200.         CreateResFile(theFile);
  201.         err := ResError;
  202.         IF err = noErr THEN
  203.           BEGIN
  204.             fRefNum := OpenResFile(theFile);
  205.             OpenAndMaybeCreateResFile := fRefNum;
  206.           END;
  207.       END;
  208.     OpenAndMaybeCreateResFile := err;
  209.   END;
  210.  
  211.   FUNCTION GetTypesToRead(paramPtr: XCMDPtr): ToGrab;  { look at parameter 2 -- }
  212. { If it's not there, we copy only XCMD's and XFCN's. }
  213. { If it's there, it's either "ALL", which means we copy all resources, }
  214. { or it tells us which resource type we should restrict our attention to. }
  215.     VAR
  216.       str: Str255;
  217.   BEGIN
  218.     GetTypesToRead := extensions;
  219.     { default behavior is to grab just XCMD's and XFCN's }
  220.     IF paramPtr^.paramCount > 1 THEN
  221.   { if there is a second parameter, it tells us to behave otherwise }
  222.       BEGIN
  223.         ZeroToPas(paramPtr, paramPtr^.params[2]^, str);
  224.         IF EqualString(str, 'ALL', FALSE, TRUE) THEN
  225.           GetTypesToRead := all
  226.   { if param 2 is "ALL", get all resource types }
  227.         ELSE GetTypesToRead := userType;
  228.       END;
  229.   END;
  230.   
  231.   PROCEDURE GoHomeComeBack(paramPtr: XCMDPtr);
  232.   { We go home and come back so that HyperCard will recognize
  233.     the newly created resources.  If 'the name' is not HyperCard,
  234.     i.e. if SuperCard is running, we don't do anything. }
  235.     VAR
  236.       hndl: Handle;
  237.       str: Str255;
  238.       shortString: String[5]; 
  239.   BEGIN
  240.     hndl := EvalExpr(paramPtr, 'the name');
  241.     IF paramPtr^.result = noErr THEN
  242.       BEGIN
  243.       ZeroToPas(paramPtr, hndl^, str);
  244.       DisposHandle(hndl);
  245.       IF EqualString(str,'HyperCard',FALSE,TRUE) THEN
  246.         BEGIN
  247.         hndl := EvalExpr(paramPtr, 'the lockscreen');
  248.         IF hndl <> NIL THEN
  249.           BEGIN
  250.           ZeroToPas(paramPtr, hndl^, str);
  251.           shortString := str;
  252.           DisposHandle(hndl);
  253.           END
  254.         ELSE shortString := 'FALSE';
  255.         hndl := EvalExpr(paramPtr, 'the lockrecent');
  256.         IF hndl <> NIL THEN
  257.           BEGIN
  258.           ZeroToPas(paramPtr, hndl^, str);
  259.           DisposHandle(hndl);
  260.           END
  261.         ELSE str := 'FALSE';
  262.         SendCardMessage(paramPtr, 'set lockscreen to true');
  263.         SendCardMessage(paramPtr, 'set lockrecent to true');
  264.         SendCardMessage(paramPtr, 'push card');
  265.         SendCardMessage(paramPtr, 'go home');
  266.         SendCardMessage(paramPtr, 'pop card');
  267.         SendCardMessage(paramPtr, CONCAT('set lockscreen to ', shortString));
  268.         SendCardMessage(paramPtr, CONCAT('set lockrecent to ', str));
  269.         END;
  270.       END;
  271.   END;
  272.  
  273.   PROCEDURE GetResources (paramPtr : XCmdPtr);
  274.     LABEL
  275.       99;
  276.     VAR
  277.       err : OSErr;
  278.       curFile, myStack, myFile : INTEGER;
  279.       fileName : Str255;
  280.       thisStack: Str255;
  281.       whatToGet: ToGrab;
  282.       alreadyOpen : BOOLEAN;
  283.       paramCount : INTEGER;
  284.       curs: CursHandle;
  285.       h: Handle;
  286.  
  287.     PROCEDURE PassReturnValue (theMsg : Str255); { set theResult }
  288.     BEGIN
  289.       paramPtr^.returnValue := PasToZero(paramPtr, theMsg);
  290.     END;
  291.  
  292.     PROCEDURE ReadAndCopyResources;
  293.   { loop through resources, read, and copy }
  294.       LABEL
  295.         98;
  296.       VAR
  297.         index, i : INTEGER;
  298.         resHandle, resAlready : Handle;
  299.         theID : INTEGER;
  300.         theCurrentType, theType : ResType;
  301.         attrs: INTEGER;
  302.         result: Handle;
  303.         name: Str255;
  304.         found: LONGINT;
  305.  
  306.     BEGIN  { loop through all resource types available in current res file }
  307.       FOR i := 1 TO Count1Types DO
  308.         BEGIN  { get the type we're looking at now }
  309.         Get1IndType(theCurrentType, i);
  310.  
  311.         CASE whatToGet OF
  312.           extensions:
  313.             { unless we had a 2nd param, we'll copy only }
  314.             { XCMD's and XFCN's }
  315.             IF (theCurrentType <> 'XFCN')
  316.               AND (theCurrentType <> 'XCMD') THEN
  317.                 Cycle;
  318. { if we did have a second param, then if it is "all" we'll }
  319. { copy everything.  Otherwise we copy only the types specified. }
  320.           userType:
  321.             BEGIN
  322.             HLock(paramPtr^.params[2]);
  323.             found := Munger(paramPtr^.params[2],0,@theCurrentType,4,NIL,0);
  324.             HUnlock(paramPtr^.params[2]);
  325.             IF found<0 THEN Cycle;
  326.             END;
  327.           all:
  328.             { We don't copy resources of type CODE, FREF, or BNDL, }
  329.             { because they can confuse the System, the Finder, }
  330.             { or the Segment Loader when copied indiscriminately. }
  331.             IF (theCurrentType = 'CODE')
  332.               OR (theCurrentType = 'FREF')
  333.               OR (theCurrentType = 'BNDL') THEN
  334.                 Cycle;
  335.           END;
  336.  
  337.       { loop through all resources of this type }
  338.         FOR index := 1 TO Count1Resources(theCurrentType) DO
  339.           BEGIN  { get a resource of this type }
  340.           SetResLoad(FALSE);
  341.           resHandle := Get1IndResource(theCurrentType, index);
  342.           GetResInfo(resHandle, theID, theType, name);
  343.           err := ResError;
  344.           IF (err <> noErr) OR (resHandle = NIL) THEN GOTO 98;
  345.           
  346.           ResrvMem(SizeResource(resHandle));
  347.           err := MemError;
  348.           IF err <> noErr THEN GOTO 98;
  349.  
  350.           SetResLoad(TRUE);
  351.           LoadResource(resHandle);
  352.           err := ResError;
  353.           IF (err <> noErr) OR (resHandle = NIL) THEN GOTO 98;
  354.           
  355.           attrs := GetResAttrs(resHandle);
  356.           DetachResource(resHandle);
  357.           
  358.           UseResFile(myStack);
  359.           SetResLoad(FALSE);
  360.           REPEAT
  361.             resAlready := Get1Resource(theType, theID);
  362.             IF resAlready <> NIL THEN
  363.               BEGIN
  364.                 RmveResource(resAlready);
  365.                 DisposHandle(resAlready);
  366.               END;
  367.           UNTIL resAlready = NIL;
  368.           REPEAT
  369.             resAlready := Get1NamedResource(theType, name);
  370.             IF resAlready <> NIL THEN
  371.               BEGIN
  372.                 RmveResource(resAlready);
  373.                 DisposHandle(resAlready);
  374.               END;
  375.           UNTIL resAlready = NIL;
  376.           SetResLoad(TRUE);
  377.           
  378.           AddResource(resHandle, theType, theID, name);
  379.           { add the new resource }
  380.           IF ResError <> noErr THEN
  381.             BEGIN
  382.             DisposHandle(resHandle);
  383.             GOTO 98;
  384.             END;
  385.  
  386.           SetResAttrs(resHandle, attrs);
  387.           ChangedResource(resHandle);
  388.           WriteResource(resHandle);
  389.           UseResFile(myFile);
  390.           { read from the source for the next resource of this type }
  391.  
  392.           98: SetResLoad(TRUE);
  393.           END;  { for index := 1 to Count1Resources }
  394.         END;  { for i := 1 to Count1Types }
  395.       UpdateResFile(myStack);
  396.     END;
  397.  
  398.   BEGIN  { procedure GetResources }
  399.     err := noErr;
  400.     curFile := CurResFile;
  401.       { store the refNum of the current resource file }
  402.     paramCount := paramPtr^.paramCount;
  403.       { count the parameters we got }
  404.     IF paramCount = 0 THEN
  405.       BEGIN
  406.       PassReturnValue('GetResources XCMD 1.6, 22 July 1989, ┬⌐1988-1989 Dartmouth College');
  407.       GOTO 99;
  408.       END;
  409.  
  410.     curs := GetCursor(watchCursor);
  411.     SetCursor(curs^^);
  412.     
  413.     ZeroToPas(paramPtr, paramPtr^.params[1]^, fileName);
  414.  
  415.     err := MyOpenResFile(fileName, myFile, alreadyOpen);
  416.     IF err <> noErr THEN GOTO 99;
  417.     { continue only if MyOpenResFile worked OK }
  418.  
  419.     err := GetFullPathnameOfThisStack(paramPtr, thisStack);
  420.     { get name of this stack }
  421.     IF err <> noErr then GOTO 99;
  422.  
  423.     err := OpenAndMaybeCreateResFile(thisStack, myStack);
  424.     { open resource fork of this stack }
  425.     IF err <> noErr then GOTO 99;
  426.  
  427.     whatToGet := GetTypesToRead(paramPtr);
  428.     UseResFile(myFile);
  429.     ReadAndCopyResources;
  430.     IF NOT alreadyOpen THEN CloseResFile(myFile);
  431.       
  432.     GoHomeComeBack(paramPtr);
  433.  
  434.     99: IF err <> noErr THEN
  435.       BEGIN
  436.       NumToStr(paramPtr, err, fileName);
  437.       PassReturnValue(CONCAT('Error ', fileName));
  438.       END;
  439.     InitCursor;
  440.     UseResFile(curFile);
  441.     { restore the resource file that was current at the start of our code }
  442.   END;
  443.  
  444. END.